﻿using System;
using System.Reflection;

namespace _5E.Utils.ReflectionHelper.Extension
{
    /// <summary>
    /// 程序说明：反射扩展类
    /// 创建作者：ahl
    /// 创建时间：2012-03-25
    /// </summary>
    public static class ReflectionExtension
    {
        #region 变量

        private static DynamicMethodCache s_MethodCache = new DynamicMethodCache();

        private static DynamicPropertyAccessorCache s_PropertyCache = new DynamicPropertyAccessorCache();

        #endregion

        #region MethodInfo

        /// <summary>
        /// 反射方法
        /// </summary>
        /// <param name="method">方法</param>
        /// <param name="classObj">类实例</param>
        /// <param name="arrParamValue">参数数组</param>
        /// <returns></returns>
        public static object FastInvoke(this MethodInfo method, object classObj = null, params object[] arrParamValue)
        {
            var invoke = method.GetFastInvoke();
            return invoke(classObj, arrParamValue);
        }

        /// <summary>
        /// 获取方法委托
        /// </summary>
        /// <param name="method">方法</param>
        /// <returns></returns>
        public static Func<object, object[], object> GetFastInvoke(this MethodInfo method)
        {
            var accessor = s_MethodCache.GetAccessor(method);
            return accessor.GetMethodInvoke();
        }

        public static bool HasAttribute<T>(this MethodInfo method, bool inherit = false) where T : Attribute
        {
            var arrAttribute = method.GetCustomAttributes(typeof(T), inherit);
            return 0 < arrAttribute.Length;
        }

        #endregion

        #region 属性

        public static object FastGetValue(this PropertyInfo property, object obj)
        {
            return obj.FastGetValue(property.Name);
        }

        public static object FastGetValue(this object obj, string propertyName)
        {
            var accessor = s_PropertyCache.GetAccessor(obj.GetType(), propertyName);
            return accessor.GetValue(obj);
        }

        #endregion
    }
}
